メインコンテンツまでスキップ

RBI プロキシの紹介

SOFTCAMP SHIELDGate 隔離ブラウザ連携のための HTTP/HTTPS プロキシサービス


📋 目次

  1. 概要
  2. RBIProxyとは?
  3. 全体アーキテクチャ
  4. 主要構成要素
  5. 動作原理
  6. PACファイル設定
  7. セキュリティメカニズム
  8. REST API
  9. 技術スタック
  10. 使用例

概要

RBIProxyはユーザーの一般的なブラウザトラフィックをSOFTCAMP SHIELDGate 隔離ブラウザ自動接続する中間プロキシサーバーです。

ユーザーは普段通りウェブブラウジングを行いますが、すべてのウェブ接続は隔離された環境(RBI)で実行され、セキュリティの脅威から安全に保護されます。

核心価値

  • 透明なセキュリティ: ユーザーエクスペリエンスを損なうことなくセキュリティを強化する(自動リダイレクト)
  • 中央集中型制御: 単一プロキシで全てのウェブトラフィックを中央で制御
  • 簡単な中継構造: URL変換およびSHIELDGate連携のみを実行(複雑なポリシーはSHIELDGateで処理)

RBIProxyとは?

RBI (Remote Browser Isolation)

リモートブラウザ隔離技術はユーザーのウェブブラウジングを物理的に隔離されたリモート環境で実行するセキュリティソリューションです。

伝統的なウェブ接続:
[ユーザーPC] ──→ [インターネットウェブサイト]

マルウェアダウンロードリスク
ゼロデイ攻撃露出
フィッシングサイト直接接続

RBI適用後:
[ユーザーPC] ──→ [隔離されたブラウザ] ──→ [インターネットウェブサイト]

マルウェアが隔離環境でのみ実行
ユーザーPCは安全

RBIProxyの役割

RBIProxyはPACフィルタリングを通過したトラフィックをSHIELDGateに変換する中継機です:

🎯 フィルタリング構造

┌──────────────────────────────────────────────────────────────┐
│ PACファイル (ユーザーPCで実行) │
│ "どのサイトはプロキシを経由し、どのサイトは直接?" │
└────────────┬─────────────────────────────┬───────────────────┘
↓ ↓
[許可されたサイト] [ブロックされたサイト]
naver.com example.com
microsoft.com unknown-site.com
内部IP (192.168.x.x) その他すべてのサイト
↓ ↓
DIRECT (プロキシを経由しない) PROXY 10.14.10.176:9999
↓ ↓
[直接接続] ┌─────────────────────────────┐
│ RBIProxyサーバー │
│ "URL変換器" │
└──────┬──────────────────────┘

URL変換を実行

https://shieldgate.softcamp.co.kr/
gate-proxy?currentTab=true&url=元のURL

HTMLリダイレクト応答

┌───────────────────────┐
│ ユーザーブラウザが │
│ 自動的に移動 │
└──────┬────────────────┘

┌─────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────┬──────────┘

┌─────────────────┐
│ rb-app │
│ (隔離ブラウザ) │
└──────┬──────────┘

[実際のウェブサイト接続]

具体的な例

例 1: naver.com 接続 (許可されたサイト)

[ユーザー] naver.com 入力  

[PAC ファイル] "naver.com? あれ?君は許可なんだね!"

[決定] "じゃあ君は DIRECT"

[結果] naver.com に直接接続 ✅ (RBIProxy を経由せず)

例2: example.com 接続 (ブロック対象サイト)

[ユーザー] example.com 入力  

[PAC ファイル] "example.com? ホワイトリストにありません"

[決定] "あなたは RBIProxy に送ります"

[RBIProxy] URL 変換
元の: http://example.com

変換: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

[HTML リダイレクト応答]
<meta http-equiv="refresh" content="0;url=変換されたURL"/>

[ユーザーブラウザ] 自動的に SHIELDGate URL に移動

[SHIELDGate] gate-proxy が rb-app(隔離ブラウザ)を実行

[rb-app] 隔離された環境で example.com にアクセス

[結果] ユーザーは隔離ブラウザで example.com を利用 ✅

全体アーキテクチャ

単純化されたフローチャート

┌─────────────────────┐
│ ユーザーPC │
│ (一般ブラウザ) │
│ Chrome / Edgeなど │
└──────────┬──────────┘

│ ① Windows プロキシ設定 (PAC)
│ - 許可サイト → DIRECT
│ - ブロックサイト → PROXY 10.14.10.176:9999

┌─────────────────────┐
│ RBIProxyサーバー │
│ (このプロジェクト) │
│ - URL変換のみ │
└──────────┬──────────┘

│ ② HTMLリダイレクト
│ shieldgate.softcamp.co.kr/
│ gate-proxy?currentTab=true&url=元のURL

┌─────────────────────┐
│ SHIELDGate │
│ (隔離ブラウザ) │
│ - gate-proxy │
└──────────┬──────────┘

│ ③ rb-app実行

┌─────────────────────┐
│ rb-app │
│ (隔離ブラウザ) │
└──────────┬──────────┘

│ ④ 実際のウェブサイト接続

┌─────────────────────┐
│ インターネットウェブサイト │
│ example.comなど │
└─────────────────────┘

┌─────────────────────┐
│ インターネットウェブサイト │
│ example.com など │
└─────────────────────┘

### 詳細データフロー

**重要**: PACファイルが1次フィルタリングを実行します!

┌─────────────────────────────────────────────────────────────────┐
│ ユーザーPC │
│ │
│ [Chrome/Edge] ユーザーがURLを入力
│ ↓ │
│ ┌─────────────────────────────────────────────┐ │
│ │ PACファイル (フィルタリング) │ │
│ │ "このサイトはどこに送る?" │ │
│ └──────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ ↓ ↓ │
│ [許可サイト] [ブロック対象] │
│ naver.com example.com │
│ ↓ ↓ │
│ DIRECT PROXY 10.14.10.176:9999 │
│ │
└──────┼──────────────┼──────────────────────────────────────────┘
│ │
↓ │ RBIProxyに渡す
[naver.com] ↓
直接接続 ┌─────────────────────────────────────────────────────────────────┐
│ RBIProxy サーバー │
│ (URL 変換器) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 1. リクエスト受信 (9999 ポート) │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 2. URL 変換 │ │
│ │ 原本:http://example.com │ │
│ │ → │ │
│ │ 変換:https://shieldgate.softcamp.co.kr/ │ │
│ │ gate-proxy?currentTab=true&url=http://example.com│
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼───────────────────────────────────────┐ │
│ │ 3. HTML リダイレクト応答 │ │
│ │ │ │
│ └──────────────────┬───────────────────────────────────────┘ │
│ │ │
└─────────────────────┼────────────────────────────────────────────┘


┌─────────────────────────────┐
│ ユーザーのブラウザが │
│ SHIELDGateに自動的に移動 │
└─────────────┬───────────────┘

┌─────────────────────┐
│ SHIELDGate │
│ gate-proxy │
└──────────┬──────────┘

│ rb-app 実行

┌─────────────────────┐
│ rb-app │
│ (隔離ブラウザ) │
└──────────┬──────────┘

│ 直接インターネット接続

┌─────────────────────┐
│ インターネットウェブサイト │
│ example.com │
└─────────────────────┘

***

## 主要構成要素

### 1. Windows PAC (Proxy Auto-Config)

**位置**: ユーザーPCのWindowsプロキシ設定

**役割**: **1次フィルタリング - サイトごとのプロキシ使用の有無を決定**

**重要**: PACファイルが最初に判断します!
- ✅ **許可サイト** (naver.com, microsoft.comなど) → `DIRECT` (プロキシを通さない)
- ⚠️ **一般サイト** (example.comなど) → `PROXY 10.14.10.176:9999` (RBIProxyで)

**例 PACファイル** (`pac.js`):

```javascript
function FindProxyForURL(url, host) \{
// 1. SHIELDGate自体はDIRECT (無限ループ防止)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr")) \{
return "DIRECT";
\}

// 2. 許可サイトリスト (例外処理)
if (dnsDomainIs(host, "naver.com") ||
dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // ← naver.com? あれ? 君は許可されてるんだね! DIRECT!
\}

// 3. 内部ネットワークはDIRECT
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 4. 基本ルール: RBIProxyに送信
return "PROXY 10.14.10.176:9999"; // ← example.com? 君はRBIProxyで!
\}

実際の動作:

ユーザーが naver.com を入力  

PAC: "naver.com? あれ? 君は許可されているんだ!"

PAC: "じゃあ君は DIRECT"

naver.com に直接接続 ✅ (RBIProxy を経由しない)


ユーザーが example.com を入力

PAC: "example.com? 許可リストにないね"

PAC: "君は RBIProxy に送る" (PROXY 10.14.10.176:9999)

RBIProxy に転送 → 次のステップへ進む

PACファイルの適用方法:

  1. 手動適用(個別PC):

    • Windows 設定 → ネットワークとインターネット → プロキシ
    • "自動プロキシ設定の使用" を有効にする
    • スクリプトアドレス:http://10.14.10.176:9999/RestAPI/pac.js
  2. GPOの適用(ドメイン一括適用):

    グループ ポリシー エディター  
    → ユーザー構成 → 基本設定 → Windows 設定 → レジストリ
    → HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings
    → AutoConfigURL = "http://10.14.10.176:9999/RestAPI/pac.js""
  3. PACファイルのダウンロード:

    # RBIProxy가 제공하는 PAC 파일
    curl http://10.14.10.176:9999/RestAPI/pac.js -o pac.js

2. RBIProxy サーバー

言語: Go (Golang)
ポート:

  • 9999: プロキシサーバー (メイン機能)
  • 80: REST API サーバー (管理/モニタリング)

デプロイ: Kubernetes (Docker コンテナ)

主要な役割: "URL 変換ツール"

PACから送信されたすべてのトラフィックを受け取ってSHIELDGate URL 形式に変換します。

┌─────────────────────────────────────────────────────┐
│ RBIProxy サーバー (URL 変換器) │
│ │
│ ① プロキシリクエスト受信 (9999 ポート) │
│ ↓ │
│ ② URL 変換 │
│ 元の: http://example.com │
│ → │
│ 変換: https://shieldgate.softcamp.co.kr/ │
│ gate-proxy?currentTab=true&url=元のURL │
│ ↓ │
│ ③ HTML リダイレクト応答 │
│ <meta http-equiv="refresh" │
│ content="0;url=変換URL"/> │
│ │
└─────────────────────────────────────────────────────┘

核心コード (src/main.go317~320行):

func redirectUrl(url string) string \{
// SHIELDGate 방식: URL을 쿼리 파라미터로 전달
return cfg.RBIProxy.RBI.BaseURL +
"gate-proxy?currentTab=true&url=" + url
\}

実際の変換例:

입력: http://example.com  

출력: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

3. SHIELDGate (隔離ブラウザ)

URL: https://shieldgate.softcamp.co.kr

構成:

  • gate-proxy: ウェブインターフェース (URLを受け取ってrb-appを実行)
  • rb-app: 隔離ブラウザエンジン (実際のウェブサイトへの接続およびレンダリング)

役割:

  • gate-proxyがURLパラメータを受け取ってrb-app(隔離ブラウザ)を実行
  • rb-appが隔離された環境で実際のウェブサイトをレンダリング
  • ユーザーに画面のみストリーミング
  • セキュリティポリシーの適用(ダウンロード/アップロード/コピー制御など)

URL 規約:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=<원본URL>

動作方式:

gate-proxy URLで入る  

gate-proxyがurlパラメータを抽出

rb-app(隔離ブラウザ)を実行

rb-appが実際のウェブサイトに直接接続

ユーザーに画面ストリーミング

例示:

変換されたURL: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com  
→ gate-proxyが rb-appを実行
→ rb-appが http://example.com に接続

動作原理

🌟 全体シナリオ: 2つの経路

ユーザーがウェブサイトにアクセスする時PACファイルがまず判断します:

ユーザーがURLを入力  

┌───────────────────────────────┐
│ PACファイル (1次フィルター) │
│ "このサイトはどこに送る?" │
└───────┬───────────────────────┘

┌────┴─────┐
↓ ↓
[許可] [ブロック]
↓ ↓
DIRECT PROXY
↓ ↓
[終了] [RBIProxy]

[SHIELDGate]

シナリオ A: 許可されたサイト (naver.com)

PACで終わるケース- RBIProxyを介さない

Step-by-Step フロー

[Step 1] ユーザーがChromeに "naver.com" を入力


[Step 2] PACファイル実行 (ユーザーPCで)
function FindProxyForURL(url, "naver.com") \{
if (dnsDomainIs(host, "naver.com")) \{
return "DIRECT"; // ← ここで決定!
\}
\}


[Step 3] PAC判断: "naver.com? え? あなたは許可されているのね!"


[Step 4] 決定: "じゃああなたはDIRECT" (プロキシを使用しない)


[Step 5] naver.comに直接接続 ✅

結果: RBIProxy、SHIELDGate どちらも経由しない

シナリオ B: ブロックされたサイト (example.com)

RBIProxy + SHIELDGateを通過するケース

Step-by-Step フロー

[Step 1] ユーザーがChromeに "example.com" を入力


[Step 2] PACファイルを実行 (ユーザーPCで)
function FindProxyForURL(url, "example.com") \{
// ホワイトリストにありません
return "PROXY 10.14.10.176:9999"; // ← ここで決定!
\}


[Step 3] PACの判断: "example.com? ホワイトリストにありませんね"


[Step 4] 決定: "あなたはRBIProxyに送ります"


[Step 5] RBIProxyが受信
→ プロキシリクエストを受信 (9999ポート)


[Step 6] URL変換を実行
→ 元の: http://example.com
→ 変換: https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com


[Step 7] HTMLリダイレクト応答を生成
→ <meta http-equiv="refresh" content="0;url=変換URL"/>
→ HTTP 202 Accepted 応答


[Step 8] ユーザーのブラウザが自動的にSHIELDGate URLに移動


[Step 9] SHIELDGate gate-proxyがURLパラメータを確認
→ url=http://example.com を抽出


[Step 10] gate-proxyがrb-app(隔離ブラウザ)を実行


[Step 11] rb-appが隔離された環境でexample.comに直接アクセス


[Step 12] ウェブサイトをレンダリング後、ユーザーに画面ストリーミング


[完了] ユーザーは隔離ブラウザでexample.comを安全に利用 ✅

シナリオ比較

段階naver.com (許可)example.com (ブロック)
PACフィルターDIRECT → 直接接続PROXY → RBIProxy로
RBIProxy通過しないURL 変換 → SHIELDGate へ
最終接続naver.com 直接rb-app(隔離ブラウザ) 経由
セキュリティレベル一般隔離環境
段階数5段階12ステップ

PACファイル設定

PACファイルとは?

**PAC (Proxy Auto-Config)**はJavaScriptで書かれたファイルで、ブラウザがどのプロキシを使用するかを動的に決定します。

RBIProxy用 PACファイル作成

RBIProxyは/RestAPI/pac.jsエンドポイントを通じてPACファイルを提供します。

基本PACファイル構造

function FindProxyForURL(url, host) \{
// 1. SHIELDGate 자체는 프록시 우회 (무한 루프 방지)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr") ||
dnsDomainIs(host, "security365.co.kr") ||
dnsDomainIs(host, "softcamp.co.kr")) \{
return "DIRECT";
\}

// 2. 내부 네트워크 (사설 IP) 우회
if (isPlainHostName(host) ||
shExpMatch(host, "*.local") ||
isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 3. 특정 도메인 예외 처리
if (dnsDomainIs(host, "microsoft.com") ||
dnsDomainIs(host, "azure.com") ||
dnsDomainIs(host, "office365.com")) \{
return "DIRECT"; // Microsoft 서비스는 프록시 우회
\}

// 4. 기본 규칙: RBIProxy를 통해 프록시
return "PROXY 10.14.10.176:9999";
\}

PACファイルの主要な関数

関数説明例示
dnsDomainIs(host, domain)ドメイン一致確認dnsDomainIs(host, "example.com")
shExpMatch(host, pattern)ワイルドカードパターンマッチングshExpMatch(host, "*.google.com")
isInNet(host, network, mask)IP ネットワーク範囲の確認isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")
isPlainHostName(host)ホスト名のみがあるか確認する(ドメインなし)isPlainHostName("localhost")

PACファイル配布方法

方法 1: RBIProxyから直接配布

RBIProxyは/RestAPI/pac.jsエンドポイントを通じてPACファイルを提供します。

# PAC 파일 접근
http://10.14.10.176:9999/RestAPI/pac.js

Windows プロキシ設定:

  1. 設定 → ネットワークとインターネット → プロキシ
  2. "設定自動検索" OFF
  3. "設定スクリプト使用" ON
  4. スクリプトアドレス:http://10.14.10.176:9999/RestAPI/pac.js

方法 2: ウェブサーバーでのデプロイ

別のウェブサーバー(Apache、Nginxなど)にPACファイルを配布することもできます。

# Nginx 설정 예시
location /proxy.pac \{
alias /var/www/html/pac.js;
types \{
application/x-ns-proxy-autoconfig pac;
\}
\}

方法 3: GPO (グループ ポリシー オブジェクト) 配布

Active Directory 環境で一括適用:

  1. グループ ポリシー管理コンソールを開く

  2. 新しい GPO の作成: "RBIProxy PAC 設定"

  3. 編集 → ユーザー構成 → 基本設定 → Windows 設定 → レジストリ

  4. 新しいレジストリ項目:

    Hive: HKEY_CURRENT_USER  
    キー パス: Software\Microsoft\Windows\CurrentVersion\Internet Settings
    値 名: AutoConfigURL
    値 タイプ: REG_SZ
    値 データ: http://10.14.10.176:9999/RestAPI/pac.js

PACファイル例外処理戦略

1. 性能最適化: 内部リソース DIRECT

// CDN, 정적 리소스는 직접 접속
if (dnsDomainIs(host, "cdn.jsdelivr.net") ||
dnsDomainIs(host, "cdnjs.cloudflare.com")) \{
return "DIRECT";
\}

2. 互換性: 特定サービスのバイパス

// Microsoft 365 서비스는 프록시 우회 (인증 문제 방지)
if (dnsDomainIs(host, "office365.com") ||
dnsDomainIs(host, "sharepoint.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

3. セキュリティ: 信頼ドメインのみRBIバイパス

// 회사 내부 시스템은 DIRECT
if (dnsDomainIs(host, "intranet.company.com") ||
dnsDomainIs(host, "erp.company.com")) \{
return "DIRECT";
\}

PACファイルテスト方法

// 테스트용 PAC 파일에 디버그 로그 추가
function FindProxyForURL(url, host) \{
var result;

if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
result = "DIRECT";
\} else if (isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0")) \{
result = "DIRECT";
\} else \{
result = "PROXY 10.14.10.176:9999";
\}

// 브라우저 콘솔에 로그 출력 (디버깅 시에만 사용)
alert("URL: " + url + "\nHost: " + host + "\nResult: " + result);

return result;
\}

オンライン PAC テスター活用:

  • PacParserPACファイルのアップロード後のテスト

セキュリティメカニズム

1. TLS MITM (Man-In-The-Middle)

RBIProxyはHTTPSトラフィックを検査するためにMITM手法を使用します。

動作過程

[ユーザーブラウザ]

│ CONNECT example.com:443

[RBIProxy]

│ ① HTTP/1.0 200 OK レスポンス
│ ② example.com用 TLS 証明書の動的発行
│ ③ ユーザーと TLS ハンドシェイク
│ ④ 暗号化されたリクエストの復号
│ ⑤ URL 確認: https://example.com/page
│ ⑥ リダイレクトレスポンスの生成

[ユーザーブラウザ]

│ 自動的に SHIELDGate に移動

[SHIELDGate]

私設証明書のインストールが必須

HTTPS MITMが正常に動作するためには、ユーザーPCがRBIProxyのCA証明書を信頼する必要があります。

証明書のダウンロード:

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

インストール方法:

  1. Windows:

    • rbiproxy_cert.cerダブルクリック
    • "証明書のインストール" をクリック
    • "ローカルコンピュータ"選択
    • "すべての証明書を次のストレージに保存"信頼できるルート認証機関
    • インストール完了
  2. GPO 一括配布:

    グループ ポリシー管理 → コンピューターの構成 → Windows 設定 → セキュリティ設定  
    → 公開キー ポリシー → 信頼されたルート認証機関
    → rbiproxy_cert.cer を追加

2. RBI 連動方式

RBIProxyは二つのRBI連携方式をサポートしています:

A. SHIELDGate方式 (現在運営中) ⭐

設定:

RBI_LINK_TYPE: SHIELDGate

コードの位置: src/main.go320行

URL形式:

https://shieldgate.softcamp.co.kr/gate-proxy?currentTab=true&url=http://example.com

処理方式:

  • RBIProxyは単純なURL変換のみを実行
  • 元のURLをクエリパラメータとして渡す
  • セキュリティポリシーはSHIELDGateで処理されます

特徴:

  • シンプルで直感的な構造
  • URLが平文で表示される
  • RBIProxyは中継器の役割のみを果たします
  • ポリシー管理をSHIELDGateに委任

B. DIRECT (JWT) 方式 (現在未使用)

設定:

RBI_LINK_TYPE: DIRECT

コードの位置: src/main.go323~342行

URL形式:

https://rbi.custom.co.kr/view?url=<JWT_TOKEN>

JWT トークンの内容(src/main.go 329~339行にハードコーディング):

\{
"ver": "1.0",
"id": "softcamp.co.kr",
"url": "http://example.com",
"policy": \{
"screenmark": "OFF", // 화면 워터마크
"key": "ON", // 키보드 입력 허용
"site": "ON", // 사이트 접근 허용
"dn": "ON", // 다운로드 허용
"up": "ON", // 업로드 허용
"media": "ON", // 미디어 재생 허용
"menu": "ON", // 메뉴 사용 허용
"clip": "ON" // 클립보드 사용 허용
\},
"exp": 1234567890 // 만료 시간 (12시간 후)
\}

特徴:

  • URLがJWTトークンで暗号化
  • トークンの有効期限設定 (12時間)

制約事項:

  • ⚠️ ポリシーがコードにハードコーディングされているなっています
  • ⚠️ すべてのリクエストに同じポリシーを適用
  • ⚠️ ユーザー別/URL別の異なるポリシーの適用不可
  • ⚠️ ConfigMapや設定ファイルで変更不可
  • 現在の運用環境では使用されていません

方式比較の要約

項目SHIELDGate方式 (運営中)DIRECT (JWT) 方式 (未使用)
設定値RBI_LINK_TYPE: SHIELDGateRBI_LINK_TYPE: DIRECT
URL 変換クエリパラメータで平文を渡すJWTトークンで暗号化
ポリシー処理SHIELDGateで処理JWT トークンに含まれる (ハードコーディング)
政策の柔軟性SHIELDGateで柔軟に管理不可能 (コード修正必要)
RBIProxyの役割単純中継器URL + ポリシーパッケージング
現在の使用状況✅ 使用中❌ 未使用

なぜSHIELDGate方式を使用するのか?

現在の運用環境分析(ConfigMap 基準):

# build/kube-deploy.yaml
RBI_LINK_TYPE: SHIELDGate # ← 실제 운영 설정
RBI_BASEURL: https://devshieldgate.softcamp.co.kr

SHIELDGate方式選択理由:

  1. 単純性:
    • RBIProxyはURL変換のみを実行します (src/main.go320行目)
    • セキュリティポリシー管理をSHIELDGateに完全に委任
    • コード修正なしでSHIELDGateでポリシー変更可能
  2. 保守性:
    • JWT方式のポリシーはsrc/main.go329~339行にハードコーディング
    • ポリシー変更時のコード修正 → ビルド → デプロイ必要
    • SHIELDGate方式はSHIELDGate 設定のみ変更やればいい。
  3. 運用の柔軟性:
    • ユーザー別/グループ別の異なるポリシーの適用はSHIELDGateで管理
    • RBIProxyはすべてのユーザーに対して同じように動作します
    • 政策変更にRBIProxy再配布不要

結論:

  • RBIProxyは**"賢いURL変換器"**役割に集中
  • 複雑な政策管理はSHIELDGateの分け前
  • シンプルで安定したアーキテクチャ

3. 無限ループ防止

RBIProxyとSHIELDGate間の無限リダイレクトを防ぐメカニズム:

PACファイルで防止:

// SHIELDGate 도메인은 DIRECT로 접속 (프록시 우회)
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 무한 루프 방지
\}

動作原理:

ユーザーが example.com を入力  

PAC: PROXY → RBIProxy に

RBIProxy: shieldgate.softcamp.co.kr/gate-proxy?url=example.com にリダイレクト

ユーザーのブラウザが shieldgate.softcamp.co.kr に接続を試みる

PAC: "shieldgate.softcamp.co.kr? DIRECT!" ← ここでブロック!

shieldgate.softcamp.co.kr に直接接続 (RBIProxy を経由せず)

無限ループ防止 ✅

もしPACで例外処理をしない場合:

❌ 無限ループ発生:
example.com → RBIProxy → shieldgate... → RBIProxy → shieldgate... (繰り返し)

REST API

RBIProxyは管理およびモニタリングのためのREST APIを提供します。

1. バージョンおよびヘルスチェック

エンドポイント: GET /またはGET /ver

curl http://10.14.10.176:9999/ver

応答:

\{
"code": 0,
"msg": "안녕, Hi, こんにちは, 你好, Chào...",
"ver": "1.0.0.5"
\}

用途:

  • サービス動作確認
  • バージョン情報の取得
  • Kubernetes Liveness/Readiness Probe

2. アクティブセッションモニタリング

エンドポイント: GET /sessions

認証:

  • localhostで接続する際に認証は不要
  • 外部接続時にBasic Authが必要です
# Basic Auth 사용
curl -u admin:password http://10.14.10.176:9999/sessions

応答:

\{
"code": 0,
"msg": "",
"total": 2,
"sessions": [
\{
"client": "192.168.1.100:48068",
"req": "GET https://example.com",
"time": "295.508µs"
\},
\{
"client": "192.168.1.101:37988",
"req": "CONNECT secure.example.com:443",
"time": "1.381s"
\}
]
\}

用途:

  • リアルタイムトラフィックモニタリング
  • 性能分析 (リクエスト処理時間)
  • ユーザー接続追跡

3. PACファイルの配布

エンドポイント: GET /RestAPI/pac.js

curl http://10.14.10.176:9999/RestAPI/pac.js

応答: JavaScript PACファイル

用途:

  • ユーザーPCのプロキシ自動設定
  • 中央でPACファイル管理

4. 独自認証書の配布

エンドポイント: GET /RestAPI/cert.cer

curl http://10.14.10.176:9999/RestAPI/cert.cer -o rbiproxy_cert.cer

応答: PEM形式のCA証明書

用途:

  • HTTPS MITMのためのプライベート証明書の配布
  • ユーザーPCにインストールして証明書警告を削除

技術スタック

言語およびフレームワーク

技術バージョン用途
Go (Golang)1.23.11メイン言語
Alpine Linux3.21.3Docker ベース イメージ
elazarl/goproxy-HTTP/HTTPS プロキシライブラリ

主要な Go パッケージ

rbiproxy/
├── cert/ # TLS証明書の動的発行 (MITM)
├── config/ # 設定ファイルのロード (config.yaml, 環境変数)
├── restapi/ # REST APIサーバー
│ └── core/ # APIハンドラー (version, sessions)
└── main.go # プロキシサーバーのメインロジック

外部依存性

  • github.com/elazarl/goproxy: HTTP/HTTPS プロキシ エンジン
  • github.com/spf13/viper: 設定ファイル管理
  • dev.azure.com/Security365/go-common:
    • JWT トークンの生成/検証
    • ロガー
    • ユーティリティ

ビルドとデプロイ

Docker イメージ ビルド:

docker build -t rbiproxy:latest -f build/Dockerfile .

バージョン管理:

  • build/version.txt: メジャー.マイナー.パッチ バージョン
  • build/version-patch.txt: パッチ番号
  • ビルド時に自動的にバージョン情報を挿入

使用例

Case 1: 企業のウェブセキュリティ強化

問題:

  • 従業員が業務中に悪性ウェブサイトにアクセス
  • ランサムウェア、マルウェアダウンロードの危険
  • フィッシングサイトへのアクセスによるアカウントの盗難

解決:

[すべての従業員PC]
↓ (GPOでPAC自動配布)
[RBIProxy]
↓ (自動リダイレクト)
[SHIELDGate隔離ブラウザ]
↓ (安全な接続)
[外部ウェブサイト]

結果: マルウェアは隔離環境でのみ実行され、従業員PCは安全

Case 2: 特定の部門のみRBIを適用

要件:

  • 開発チームは自由なインターネット使用が必要です (DIRECT)
  • 一般部門はRBIを通じたセキュリティ接続

実装:

// 개발팀 IP 대역
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 IP 대역은 DIRECT
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 그 외 일반 부서는 RBIProxy 사용
if (/* 예외 조건들 */) \{
return "DIRECT";
\}

return "PROXY 10.14.10.176:9999";
\}

Case 3: 高リスクカテゴリのみRBI適用

要件:

  • 信頼できるサイト(Microsoft, Google)はDIRECT
  • 知られていないサイトのみRBI適用

実装:

function FindProxyForURL(url, host) \{
// 신뢰 도메인 리스트
var trustedDomains = [
"microsoft.com", "google.com", "github.com",
"stackoverflow.com", "azure.com"
];

for (var i = 0; i < trustedDomains.length; i++) \{
if (dnsDomainIs(host, trustedDomains[i])) \{
return "DIRECT";
\}
\}

// 기타 사이트는 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Case 4: モニタリングおよびロギング

要件:

  • リアルタイムトラフィックモニタリング
  • どのユーザーがどのサイトにアクセスしているかを追跡

実装:

# 실시간 활성 세션 모니터링
watch -n 2 'curl -s http://10.14.10.176:9999/sessions | jq .'

# 로그 파일 실시간 확인 (Kubernetes)
kubectl logs -f deployment/rbiproxy -n shieldinfo-dev

# 특정 사용자 IP 필터링
kubectl logs deployment/rbiproxy -n shieldinfo-dev | grep "192.168.1.100"

デプロイメントアーキテクチャ

Kubernetes 環境

┌────────────────────────────────────────────────────────────┐
│ Kubernetes クラスター │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Namespace: shieldinfo-dev │ │
│ │ │ │
│ │ ┌──────────────────┐ ┌──────────────────┐ │ │
│ │ │ ConfigMap │───→│ Deployment │ │ │
│ │ │ rbiproxy-config │ │ │ │ │
│ │ │ │ │ ┌────────────┐ │ │ │
│ │ │ RBI_BASEURL │ │ │ rbiproxy │ │ │ │
│ │ │ RBI_LINK_TYPE │ │ │ Container │ │ │ │
│ │ │ RBIPROXY_PORT │ │ │ │ │ │ │
│ │ └──────────────────┘ │ │ Port:9999 │ │ │ │
│ │ │ └────────────┘ │ │ │
│ │ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────▼─────────┐ │ │
│ │ │ Service │ │ │
│ │ │ rbiproxy │ │ │
│ │ │ │ │ │
│ │ │ Port 80, 9999 │ │ │
│ │ └────────┬─────────┘ │ │
│ └────────────────────────────────────┼────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────▼────────────────┐ │
│ │ Namespace: kube-system │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ rke2-ingress-nginx-controller │ │ │
│ │ │ │ │ │
│ │ │ - containerPort.rbiproxy: 9999 │ │ │
│ │ │ - tcp-services ConfigMap 参照 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────────▼──────────────────────────┐ │ │
│ │ │ Service (NodePort/LoadBalancer) │ │ │
│ │ │ Port 9999 外部 露出 │ │ │
│ │ └───────────────────┬──────────────────────────┘ │ │
│ └──────────────────────┼───────────────────────────────┘ │
│ │ │
└─────────────────────────┼─────────────────────────────────────┘

│ NodePort または LoadBalancer

┌───────────────┐
│ 外部 接続 │
│ (ユーザー PC) │
└───────────────┘

高可用性構成

マルチレプリカデプロイメント:

spec:
replicas: 3 # 3개 인스턴스 실행
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 최대 1개까지만 동시 다운
maxSurge: 1 # 최대 1개까지 추가 생성

HPA (Horizontal Pod Autoscaler):

# CPU 사용률 기반 자동 스케일링
kubectl autoscale deployment rbiproxy \
--cpu-percent=70 \
--min=2 \
--max=10 \
-n shieldinfo-dev

環境変数

Kubernetes ConfigMapを通じて設定を注入します。

必須環境変数

環境変数例の値説明
RBIPROXY_PORT9999プロキシサービスポート
RBI_BASEURLhttps://shieldgate.softcamp.co.krSHIELDGate サーバーアドレス (末尾に/自動追加されました)
RBI_LINK_TYPESHIELDGate連携方式 (SHIELDGateまたはDIRECT)
TZAsia/Seoulタイムゾーン (ログ時間表示用)

選択環境変数

環境変数デフォルト値説明
LOG_LEVELinfoログレベル (error, warn, info, debug)
RESTAPI_JWT_SECRET_B64自動生成JWT署名シークレット (Base64)

環境変数の優先順位

1位: 環境変数 (ConfigMap/環境変数)  
2位: config.yaml ファイル
3位: コマンドラインフラグ

Kubernetes デプロイ時に ConfigMap の環境変数が最優先で適用されます。


性能とリソース

リソース要件

環境CPU RequestCPU LimitMemory RequestMemory LimitReplicas
開発/テスト100m500m200Mi512Mi1
小規模運営200m700m300Mi1Gi2
中規模運営500m1000m500Mi2Gi3
大規模運用1000m2000m1Gi3Gi5+

予想処理量

単一インスタンス基準(リソース: 700m CPU, 1Gi メモリ):

  • 同時接続: 約500~1,000個
  • 秒あたりのリクエスト: 約100~200 req/s
  • 応答時間: 平均 10~50ms (リダイレクトのみ)

実際の性能は次の要因によって異なります:

  • ネットワーク帯域幅
  • SHIELDGate 応答速度
  • TLS ハンドシェイクオーバーヘッド

ボトルネック

  1. TLS MITM: 各 HTTPS リクエストごとにハンドシェイクが必要 → CPU 使用量の増加
  2. 動的認証書発行: ドメイン別証明書生成 → メモリ使用量増加
  3. ログ記録: すべてのリクエストをログに記録すると I/O 負荷が増加

最適化のヒント:

  • ログレベルをwarnまたはerrorを下げる
  • レプリカ数の増加による負荷分散
  • SHIELDGateサーバーと同じネットワークに配置(レイテンシの減少)

ログとモニタリング

ログ形式

2026-04-01 15:23:45 [INFO] Local HTTP Request - IP: 192.168.1.100:52341, URL: http://example.com, Method: GET
2026-04-01 15:23:45 [INFO] Local [GET http://example.com] code=200 OK elap=12ms

2026-04-01 15:24:10 [INFO] Local HTTPS CONNECT Request - IP: 192.168.1.100:52342, Host: secure.example.com:443
2026-04-01 15:24:10 [INFO] Local HTTPS Detail - IP: 192.168.1.100:52342, Method: GET, URL: https://secure.example.com/
2026-04-01 15:24:10 [INFO] Local [CONNECT secure.example.com:443] GET https://secure.example.com/ code=200 OK elap=45ms

ログ分類

ログタイプ説明意味
Local HTTP Request一般的なブラウザのHTTPリクエスト受信ユーザーがHTTPサイトに接続しようとしています。
Local HTTPS CONNECT一般的なブラウザのHTTPS CONNECTリクエストユーザーがHTTPSサイトに接続しようとしています
Local HTTPS DetailHTTPS リクエストの実際の内容TLS 復号化後確認された URL

Prometheus メトリック (今後追加可能)

# アクティブセッション数
rbiproxy_active_sessions_total

# リクエスト処理時間 (ヒストグラム)
rbiproxy_request_duration_seconds

# リクエスト数
rbiproxy_requests_total

# エラー発生数
rbiproxy_errors_total\{type="tls|redirect|connection"\}

セキュリティ考慮事項

1. 独自認証書管理

危険:

  • RBIProxyのCA証明書が漏洩するとMITM攻撃が可能
  • 認証書の有効期限切れ時のサービス中断

対応:

  • CA 証明書ファイル(proxy_cert.pem, proxy_pkey.pem)を安全に保管
  • Kubernetes Secretで管理 (ConfigMapの代わりに)
  • 定期的な証明書の更新(例:1年ごと)

証明書の再生成:

openssl req -x509 -newkey rsa:4096 \
-keyout proxy_pkey.pem \
-out proxy_cert.pem \
-sha256 -days 3650 -nodes \
-subj "/C=KR/ST=Seoul/O=Security365/CN=RBIProxy" \
-addext "subjectAltName=DNS:RBIProxy"

2. REST API アクセス制御

危険:

  • /sessionsAPIでユーザーのトラフィックを露出可能

対応:

  • Basic Auth 設定 必須
  • localhost 外部接続時 認証強制
  • Kubernetes NetworkPolicyでAPIアクセス制限

Basic Auth 設定 (config.yaml):

restapi:
basicAuth:
username: admin
password: strong_password_here

3. 無限ループ防止

危険:

  • PACファイルでSHIELDGateをDIRECTで処理しないと無限ループが発生します

対応:

// PAC 파일에 반드시 포함
if (dnsDomainIs(host, "shieldgate.softcamp.co.kr")) \{
return "DIRECT"; // 프록시 우회
\}

4. 内部ネットワークの隔離

推奨構成:

DMZ:        [RBIProxy] ← ユーザーPCアクセス  
Internal: [SHIELDGate] ← RBIProxyのみアクセス可能

NetworkPolicy の例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: rbiproxy-policy
spec:
podSelector:
matchLabels:
app: rbiproxy
ingress:
- from:
- namespaceSelector:
matchLabels:
name: dmz
ports:
- protocol: TCP
port: 9999

高度な設定

1. 複数のRBIサーバーのサポート

シナリオ: 部署ごとに異なるRBIサーバーを使用

実装方法:

  • RBIProxyを複数展開 (それぞれ異なるRBI_BASEURL設定)
  • PACファイルでIP範囲ごとに異なるプロキシを指定
function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 개발팀 (10.14.20.0/24) → RBIProxy-Dev
if (isInNet(clientIP, "10.14.20.0", "255.255.255.0")) \{
return "PROXY 10.14.10.100:9999";
\}

// 일반 부서 → RBIProxy-Prod
return "PROXY 10.14.10.176:9999";
\}

2. ホワイトリスト中央管理

現在: PACファイルに例外ドメインをハードコーディング

改善策:

  • 中央管理システム(DB, Redisなど)での例外ドメインリスト管理
  • RBIProxyが動的にロードされます
  • PACファイルをテンプレートとして生成

3. 地域別RBIサーバー分散

シナリオ: 支社ごとに近くのRBIサーバーを使用

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// 서울 본사 (10.14.0.0/16)
if (isInNet(clientIP, "10.14.0.0", "255.255.0.0")) \{
return "PROXY 10.14.10.176:9999"; // 서울 RBIProxy
\}

// 부산 지사 (10.20.0.0/16)
if (isInNet(clientIP, "10.20.0.0", "255.255.0.0")) \{
return "PROXY 10.20.10.50:9999"; // 부산 RBIProxy
\}

return "DIRECT";
\}

FAQ (よくある質問)

Q1: RBIProxyがダウンするとインターネットは使えなくなりますか?

A: はい。プロキシがダウンすると、すべてのウェブ接続が不可能になります。

対応策:

  • 高可用性構成: マルチレプリカデプロイメント (最小2つ)

  • Failover: PACファイルにバックアッププロキシを指定

    // 메인 프록시 실패 시 백업 프록시 사용
    return "PROXY 10.14.10.176:9999; PROXY 10.14.10.177:9999; DIRECT";
  • モニタリング: Prometheus + Grafanaでリアルタイムの状態確認

  • アラーム: Alertmanagerでダウン時に即時通知

Q2: 特定のユーザーにのみRBIを適用できますか?

A: はい。PACファイルでIPレンジまたはユーザーごとの分岐が可能です。

function FindProxyForURL(url, host) \{
var clientIP = myIpAddress();

// VIP/임원진은 DIRECT 접속 허용
if (isInNet(clientIP, "10.14.1.0", "255.255.255.0")) \{
return "DIRECT";
\}

// 일반 직원은 RBIProxy 경유
return "PROXY 10.14.10.176:9999";
\}

Q6: ログからどのような情報を確認できますか?

A: 次の情報をログに記録します:

  • クライアント IP アドレス
  • リクエストURLおよびメソッド
  • 応答時間
  • HTTP ステータスコード

個人情報保護:

  • POST ボディはロギングしません
  • クッキー、Authorization ヘッダーはログに記録しません
  • URLのクエリパラメータはログに記録されます(機密情報を含む可能性があります)

制限事項および既知の問題

1. WebSocket サポートの制限

現象: WebSocket 接続が正常に動作しない可能性があります

原因: HTTP Upgrade リクエスト処理未対応

解決: WebSocketを使用するサイトはPAC例外処理

// WebSocket 사용 사이트 예외
if (dnsDomainIs(host, "slack.com") ||
dnsDomainIs(host, "teams.microsoft.com")) \{
return "DIRECT";
\}

2. 一部の認証方式の互換性問題

現象: クライアント証明書ベースのサイト接続不可

原因: MITMプロセスでクライアント証明書が送信されない

解決: 当該サイトをPAC例外処理

3. HTTP/2 および HTTP/3

現在の状態: HTTP/1.1のみ完全サポート

HTTP/2: goproxy ライブラリの制約により制限されたサポート

HTTP/3: 未サポート (QUICプロトコル)


関連文書

インストールおよび運用

  • [構築ガイド](../../内部文書/構築-インストール-運用ガイド/RBI Proxy/RBIProxy構築ガイド.md): Kubernetesデプロイ全体手順
  • [環境変数](../../内部文書/構築-インストール-運営ガイド/RBI Proxy/RBIProxy config.js ガイド.md): ConfigMap 設定詳細
  • main.go コード分析: 内部動作原理

REST API

プロジェクト情報

  • README.md: プロジェクト概要と変更履歴

ライセンスおよびオープンソース

使用中のオープンソース

ライブラリライセンス用途
elazarl/goproxyBSD-3-ClauseHTTP/HTTPS プロキシ エンジン
spf13/viperMIT設定ファイル管理

変更履歴

RBIProxyは元々lqqyt2423/go-mitmproxyを基にしたが、elazarl/goproxyに変更されました (v1.0.0.1, 2024-06-11)。

変更理由:

  • より良いHTTPS処理
  • 安定したMITM機能
  • 活発なコミュニティサポート

要約

RBIProxyは:

  • ユーザーPCとインターネットの間の透明なセキュリティ層
  • Windows PACを通じて自動的に適用動作するプロキシ
  • SOFTCAMP SHIELDGateと連携してウェブアクセスを隔離環境に切り替える
  • PACファイルを通じて選別的フィルタリング無限ループ防止のために
  • Kubernetesで簡単にデプロイおよび拡張可能

一行の要約:
"PACフィルタリングを通過したトラフィックをSHIELDGateに変換するURL変換プロキシ"


次のステップ

  1. [構築ガイド](../../内部文書/構築-インストール-運用ガイド/RBI Proxy/RBIProxy構築ガイド.md)を参考にして配布
  2. PACファイルを環境に合わせてカスタマイズ
  3. ユーザーPCにCA証明書をインストール
  4. Windows GPOでPAC設定を一括配布
  5. モニタリングダッシュボードの構築 (/sessionsAPI 活用)

お問い合わせ:

  • 技術サポート:SOFTCAMP
  • プロジェクト管理: nicejh

最終修正: 2026-04-01